#include<bits/stdc++.h>
#define N 1010
// #define int long long
#define ll long long
#define il inline
#define ct const
#define dl double
#define pk push_back
#define fi first
#define se second
#define sit set<pii>::iterator
#define pii pair<int,int>
using namespace std;
char buf[(1<<21)+5],*p1,*p2;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
int read(){
	int f=0,x=0;
	char ch=getchar();
	while(!isdigit(ch)){f|=(ch=='-');ch=getchar();}
	while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
	return f?-x:x;
}
char f__[40];
il void write(int x){
	int cnt=0;
	if(x<0){
		putchar('-');x=-x;
	}
	if(!x) putchar('0');
	while(x){
		f__[cnt++]=x%10+'0';x/=10;
	}
	while(cnt) putchar(f__[--cnt]);
}
int n,m,mod,a[N][N],Q;
ll ans[N*N<<1];
il void Add(int &a,int b){
    a=a+b>=mod?a+b-mod:a+b;
}
struct ques{
    int ax,ay,bx,by,id;
} ;
struct SEG{
    #define ls (w<<1)
    #define rs (w<<1|1)
    ll mul[N<<2];
    il void push_up(int w){
        mul[w]=mul[ls]*mul[rs]%mod;
    }
    il void build(int w,int l,int r){
        mul[w]=1;
        if(l==r) return;
        int mid=(l+r)>>1;
        build(ls,l,mid);build(rs,mid+1,r);
    }
    il void update(int w,int l,int r,int x,int k){
        if(l==r){
            mul[w]=mul[w]*k%mod;return;
        }
        int mid=(l+r)>>1;
        if(x<=mid) update(ls,l,mid,x,k);
        else update(rs,mid+1,r,x,k);
        push_up(w);
    }
    il int query(int w,int l,int r,int L,int R){
        if(L>r||R<l) return 1;
        if(L<=l&&R>=r) return mul[w];
        int mid=(l+r)>>1;
        return (ll)query(ls,l,mid,L,R)*query(rs,mid+1,r,L,R)%mod;
    }
} ST;
il void insert(int x){
    for(int i=1;i<=m;++i) ST.update(1,1,m,i,a[x][i]);
}
il bool cmp1(ques u,ques v){
    return u.ax<v.ax;
}
il bool cmp2(ques u,ques v){
    return u.bx>v.bx;
}
il void solve(int l,int r,vector<ques> now){
    if(l>r) return;
    int mid=(l+r)>>1;vector<ques> L,R;
    ST.build(1,1,m);insert(mid);
    for(auto x:now){
        if(x.ax<=mid&&x.bx>=mid){
            ans[x.id]=ST.query(1,1,m,x.ay,x.by);
            // if(x.id==1) cerr<<x.
            if(x.ax<mid){
                // if(x.id==1) cerr<<"ERROR";
                L.pk(x);
            }
            if(x.bx>mid){
            // if(x.id==1) cerr<<"ERROR";
                R.pk(x);
            }
        }
    }
    sort(L.begin(),L.end(),cmp1);
    sort(R.begin(),R.end(),cmp2);
    ST.build(1,1,m);
    for(int i=mid-1;i>=l;--i){
        insert(i);
        // if(mid==3) cerr<<ST.query(1,1,m,3,4)<<" ";
        while(!L.empty()&&L.back().ax==i){
            ques x=L.back();L.pop_back();
            // if(x.id==1) cerr<<i<<" "<<mid<<" ";
            ans[x.id]=ans[x.id]*ST.query(1,1,m,x.ay,x.by)%mod;
        }
        if(L.empty()) break;
    }
    ST.build(1,1,m);
    for(int i=mid+1;i<=r;++i){
        insert(i);
        while(!R.empty()&&R.back().bx==i){
            ques x=R.back();R.pop_back();
            ans[x.id]=ans[x.id]*ST.query(1,1,m,x.ay,x.by)%mod;
        }
        if(R.empty()) break;
    }
    L.clear();R.clear();
    for(auto x:now){
        if(x.bx<mid) L.pk(x);
        if(x.ax>mid) R.pk(x);
    }
    now.clear();
    solve(l,mid-1,L);solve(mid+1,r,R);
}
signed main(){
    freopen("tsuki.in","r",stdin);
    freopen("tsuki.out","w",stdout);
    n=read();m=read();mod=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j) a[i][j]=read();
    Q=read();vector<ques> tmp;
    // Q<<=1;
    // cerr<<Q<<" ";
    for(int i=1;i<=Q;++i){
        ques x;ans[i]=1;
        x.ax=read();x.ay=read();x.bx=read();x.by=read();x.id=i;tmp.pk(x);
    }
    // for(int i=0;i<Q;++i) tmp.pk(tmp[i]);
    // Q<<=1;
    // cerr<<"ERROR";
    solve(1,n,tmp);
    ll Ans=0;
    for(int i=1;i<=Q;++i) Ans=(Ans+(ans[i]^(ll)i))%147744151;
    write(Ans);
   cerr<<"\n"<<(dl)clock()/CLOCKS_PER_SEC;
	return 0;
}